"""
===================================================
    FILENAME: objects.py
    东川路集群智能运输大队
    指导老师：张庆昊，邬明宇，卢俊国
    小组成员：景序，谭睿佳，于沛龙
===================================================
"""

from rflysim.config import Position

class Line:
    def __init__(self, startPos: list, endPos: list):
        self.startPos = startPos
        self.endPos = endPos

class Shape:
    """
    nZoneType:
    0: polygon
    1: circle:
        currently not included
    3: rectangle
    """
    def __init__(self, nZoneType: int, vertices: list[list], radius = None):
        self.nZoneType = nZoneType
        if nZoneType == 0:
            self.vertices = vertices
            self.radius = None
            self.center = None
        elif nZoneType == 3:
            self.vertices = vertices
            self.radius = None
            self.center = [sum(vertices[i][0] for i in range (4))/4, sum(vertices[j][1] for j in range (4))/4]
        elif nZoneType == 1:
            self.vertices = None
            self.center = vertices[0]
            self.radius = radius

class Package:
    def __init__(self, packageInfo, destinationID):
        self.ID = packageInfo.id
        self.weight = packageInfo.weight
        self.destinationID = destinationID
        """
        status:
            0:in pick area
            1:on vehicle
            2:in delivery area
        """
        self.status = packageInfo.status
        self.areaID = packageInfo.area_id
        self.vehicleID = packageInfo.vehicle_id
        self.type = None     # -1 when not in any vehicle

    def setType(self, type):
        self.type = type

"""
23:barrier
12:pick_light
14:pick_medium
15:pick_heavy
16:pick_overweight
22:deliver_light
24:deliver_medium
25:deliver_heavy
26:deliver_overweight
"""

class Barrier:
    def __init__(self, ID, shape: Shape):
        self.ID = ID
        self.shape = shape

    def getType(self):
        return "barrier"

"""
for pick, delivery and vehicle:
    content:current list of packages
"""

class Pick:
    """pick area objects"""
    def __init__(self, ID, shape: Shape, simType, packages:list[Package]):
        self.ID = ID
        self.shape = shape
        self.sides = [Line(shape.vertices[i], shape.vertices[(i+1)%len(shape.vertices)]) for i in range(3)]
        self.content = packages
        self.weight = None
        if simType == 12:
            self.weight = "light"
        elif simType == 14:
            self.weight = "medium"
        elif simType == 15:
            self.weight = "heavy"
        elif simType == 16:
            self.weight = "overload"
        for pkg in self.content:
            pkg.setType(self.weight)

    def getType(self):
        return "pick" + "_" + self.weight
    
    def pickOutContent(self, goodsID):
        self.content.remove(pkg for pkg in self.content if pkg.ID == goodsID)

    def getSingleContentWeight(self):
        return self.content[0].weight

class Delivery:
    """deliver area objects"""
    def __init__(self, ID, shape: Shape, simType):
        self.ID = ID
        self.shape = shape
        self.sides = [Line(shape.vertices[i], shape.vertices[(i+1)%len(shape.vertices)]) for i in range(3)]
        self.weight, self.content = None, []
        if simType == 22:
            self.weight = "light"
        elif simType == 24:
            self.weight = "medium"
        elif simType == 25:
            self.weight = "heavy"
        elif simType == 26:
            self.weight = "overload"

    def getType(self):
        return "delivery" + "_" + self.weight
    
    def sendInContent(self, goods: Package):
        self.content.append(goods)

    def getSingleContentWeight(self):
        return self.content[0].weight

class Vehicle:
    def __init__(self, ID, capacity, velcoity, vType, startPos:Position):
        """
        Args:
            ID(int):           get from get_vehicle_ids()
            capacity(int):     max load
            velocity(int):     max speed
            content(list[Package]):     current lis of packages
        """
        self.ID = ID
        self.capacity = int(capacity)
        self.velocity = int(velcoity)
        self.content = []
        self.startPos = startPos
        self.type = None
        if vType == 0:
            self.type = "small"
        elif vType == 1:
            self.type = "medium"
        elif vType == 2:
            self.type = "large"

        # 协同状态参数（超限货物专用）
        self.collaborator_ids = []  # 协同车辆ID列表
        self.is_collaborating = False  # 是否处于协同状态
        self.collab_task_id = None  # 绑定的协同任务ID
        self.priority = 0

    def getContent(self):
        return self.content

    def addContent(self, goods: Package):
        self.content.append(goods)

    def getPriority(self):
        return self.priority

    def addPriority(self, priority):
        self.priority += priority

    def refreshPriority(self):
        self.priority = 0

    def removeContent(self, goodsID):
        for goods in self.content:
            if goods.ID == goodsID:
                self.content.remove(goods)
                break

    def add_collaborator(self, vehicle_id):
        """添加协同车辆，≥2辆时标记为协同状态"""
        if vehicle_id not in self.collaborator_ids and vehicle_id != self.ID:
            self.collaborator_ids.append(vehicle_id)
            self.is_collaborating = len(self.collaborator_ids) >= 2

    def remove_collaborator(self, vehicle_id):
        """移除协同车辆，<2辆时取消协同状态"""
        if vehicle_id in self.collaborator_ids:
            self.collaborator_ids.remove(vehicle_id)
            self.is_collaborating = len(self.collaborator_ids) >= 2

class Task:
    """
    任务类：关联取货区、送货区与车辆，支持基础/超限货物任务
    纯逻辑实现任务状态管理，无外部依赖
    """
    def __init__(self, pkg:Package):
        self.package = pkg
        self.task_id = pkg.ID
        self.pick_area_id = pkg.areaID  # 关联取货区id（Pick对象id，同algorithm.py）
        self.delivery_area_id = pkg.destinationID  # 关联送货区id（Delivery对象id，同algorithm.py）
        self.goods_type = pkg.type  # 货物类型（light/medium/heavy/overload）
        # 货物重量（匹配车辆max_weight，参考比赛超限货物需≥2车协同）
        self.goods_weight = pkg.weight
        # 任务状态（pending/assigned/transporting/completed/timeout）
        self.status = "pending"
        self.assigned_vehicles = []  # 分配的车辆ID列表
        # 时间参数（用于评分：运输效率/协同性）
        self.start_time = None  # 运输开始时间
        self.end_time = None  # 运输结束时间
        self.stay_start_time = None  # 到达送货区的开始停留时间
        # 协同参数（超限任务专用）
        self.effective_follow_time = 0  # 有效跟随时长（秒）
        self.sample_count = 0  # 协同状态采样次数（每0.5秒1次）
